﻿using System;
using System.Collections.Generic;
using System.Linq;
using AppService.Questionnaire.Input;
using AppService.Questionnaire.Output;
using Common.ResultMessage;
using Repository.EF;
using Repository.Repositories.EFRepository;
using Repository.Repositories.Interfaces;

namespace AppService.Questionnaire
{
    public class QuestionnaireService
    {
        private SkillPointsRepository _skillPointsRepository = new SkillPointsRepository();
        private IEmpRepository _empRepository = new EmpRepository();

        public QuestionnaireOutput QueryQuestionnaire()
        {
            var questionnaire = new QuestionnaireOutput();

            var allSkillPoints = _skillPointsRepository.QueryAll();

            questionnaire.SkillPoints = BuildSkillPointsTree(allSkillPoints);

            return questionnaire;
        }

        public BizResultMessage Save(QuestionnaireInput questionnaireInput)
        {
            BizResultMessage result = new BizResultMessage();

            if (questionnaireInput == null)
                throw new Exception("参数不能为空");
                //result.Msg = "参数不能为空";

            if (string.IsNullOrEmpty(questionnaireInput.EmpName) || string.IsNullOrEmpty(questionnaireInput.EmpNum))
                result.Msg = "工号或姓名不能为空";

            if (questionnaireInput.SkillPoints == null || questionnaireInput.SkillPoints.Count == 0)
                throw new Exception("技能不能为空"); 

            var emp = _empRepository.FirstOrDefault(e => e.Num == questionnaireInput.EmpNum);
            if (emp == null)
            {
                emp = new Emp()
                {
                    Name = questionnaireInput.EmpName,
                    Num = questionnaireInput.EmpNum,
                    EmpSkillPoints = new List<EmpSkillPoints>()
                };
            }
            else
            {
                emp.EmpSkillPoints.Clear();
                _empRepository.Persist(emp);
            }
                
            foreach (var skillPoint in questionnaireInput.SkillPoints)
            {
                emp.EmpSkillPoints.Add(new EmpSkillPoints()
                {
                    SkillPointId = skillPoint.Id,
                    Degree = skillPoint.Degree
                });
            }

            _empRepository.Persist(emp);

            result.Success = true;
            return result;
        }


        private List<SkillPointOutput> BuildSkillPointsTree(List<SkillPoints> skillPoints)
        {
            var skillPointsTree = new List<SkillPointOutput>();

            Loop(skillPointsTree, skillPoints);

            return skillPointsTree;
        }

        private void Loop(List<SkillPointOutput> target, List<SkillPoints> skillPoints)
        {
            skillPoints = skillPoints.OrderByDescending(s => s.Sort).ToList();
            for (var index = 0; index < skillPoints.Count; index++)
            {
                var item = skillPoints[0];
                if (item.ParentId == null)
                {
                    AddSubNode(target, item);
                    skillPoints.Remove(item);
                }
                else
                {
                    var parent =
                        target.Union(target.SelectMany(x => x.SubSkillPoint)).FirstOrDefault(p => p.Id == item.ParentId);
                    if (parent != null)
                    {
                        AddSubNode(parent.SubSkillPoint, item);
                        skillPoints.Remove(item);
                    }
                }
            }
            if (skillPoints.Count > 0)
            {
                Loop(target, skillPoints);
            }
        }

        private void AddSubNode(List<SkillPointOutput> tree, SkillPoints skillPoints)
        {
            tree.Add(new SkillPointOutput
            {
                Id = skillPoints.Id,
                Name = skillPoints.Name,
                SubSkillPoint = new List<SkillPointOutput>()
            });
        }
    }
}
